﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using csIOC0640;
using System.Timers;
using System.Configuration;

namespace Common
{
    public class IO_C0640 : I_IO_Card
    {

        private readonly static object locker = new object();
        public static readonly IO_C0640 instance = new IO_C0640();
        System.Timers.Timer tmr = new System.Timers.Timer(10);
        volatile ushort _ReadData = 0;
        volatile ushort Trg = 0;
        volatile ushort Continue = 0;
        public event Action<ushort> TrigEvent;
        public bool isOpen { get; set; }
        public ushort ReadData { get { return _ReadData; } set { _ReadData = value; } }
        private bool inited = false;

        private IO_C0640()
        {
            Start();
            tmr.Elapsed += tmr_Elapsed;
        }

        public void Start()
        {
            try
            {
                if (!inited)
                {
                    int wRtn = IOC0640.ioc_board_init();
                    if (wRtn == 0)
                    {
                        throw new Exception("Driver Inital Error!!Error Code:" + wRtn.ToString());
                    }
                    inited = true;
                }
                if (!tmr.Enabled)
                {
                    tmr.Start();
                }
             
                isOpen = true;
          //      WriteBit(GenneralConfig.instance.module.DO_RUN, true);
              //  WriteBit(GenneralConfig.instance.module.DO_READ_OK, true);

            }
            catch(Exception ex)
            {
                isOpen = false;
            }
        }

        public  void Stop()
        {
            tmr.Stop();
            isOpen = false;
      //      WriteBit(GenneralConfig.instance.module.DO_RUN,false);
        }

        void tmr_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (locker)
            {
                tmr.Stop();
                _ReadData = (ushort)(Read() & 0xffff);
                Trg = (ushort)(_ReadData & (_ReadData ^ Continue));
                Continue = _ReadData;
                if (Trg != 0 && TrigEvent != null)
                {
                    TrigEvent(Trg);
                }
                tmr.Start();
            }
        }


        public  void Write(uint val)
        {
            if (isOpen)
            {
                uint wRtn = IOC0640.ioc_write_outport(0, 0, (~val) & 0xffff);
                if (wRtn != 0)
                {
                    throw new Exception("Driver Write Error!!Error Code:" + wRtn.ToString());
                }
            }
        }

        public uint Read()
        {
            try
            {
                if (isOpen)
                {
                    int wDIVal = 0;

                    wDIVal = IOC0640.ioc_read_inport(0, 0);
                    return (uint)(~wDIVal);
                }
                else
                    return 0;
            }
            catch 
            {
                
                return 0;
            }
        }

        public bool ReadBit(uint bitNo)
        {
            try
            {
                if (isOpen)
                {
                 int wDIVal = IOC0640.ioc_read_inbit(0, (ushort)bitNo);
                    return wDIVal > 0 ? false : true;
                }
                else
                    return false;
            }
            catch 
            {
                return false;
            }
        }

        public void AddSubscriber(Action<ushort> method)
        {
            TrigEvent += method;
        }

        public void WriteBit(int bitNo, bool val)
        {
            if (isOpen)
            {
                uint wRtn = IOC0640.ioc_write_outbit(0, (ushort)bitNo, val?0:1);
                //if (wRtn != 0)
                //{
                //    throw new Exception("Driver Write Error!!Error Code:" + wRtn.ToString());
                //}
            }
        }



    }
}
